import { RouteRecordRaw } from 'vue-router';
import { HttpUtil } from '@/utils/HttpUtil';
import path from 'path';
import { Authority } from '@/store/modules/account/info';
import { Route } from '@/router/index';

/**
 * @deprecated
 **/
export const decorateAuthority = (authority?: Partial<Authority>): Authority => {
  if (authority) {
    return {
      roles: authority?.roles ?? [],
      accesses: authority?.accesses ?? [],
    };
  } else {
    return {
      roles: [],
      accesses: [],
    };
  }
};

export const decorateRoute = (route: RouteRecordRaw, parent?: RouteRecordRaw): Route => {
  // console.log('route', route);
  // console.log('parent', parent);
  if (route.path) {
    if (HttpUtil.isExternal(route.path)) {
      if (route.children && route.children.length > 0) {
        console.error(route);
        console.error('Components that have children should not have external links');
      }
    } else {
      route.path = path.join(parent?.path ?? '', route.path);
    }
  } else {
    console.error(route);
    console.error('The component has no path!');
  }
  if (!route.name) {
    route.name = Symbol.for(route.path);
  }
  // console.log('route', route);
  // console.log('parent', parent);
  if (route.meta) {
    if (parent && parent.meta) {
      const source = route.meta;
      route.meta = {
        title: source.title ?? '',
        icon: source.icon ?? '',
        affix: source.affix ?? parent.meta?.affix,
        hidden: source.hidden ?? parent.meta?.hidden,
        noCache: source.noCache ?? parent.meta?.noCache,
        breadcrumb: source.breadcrumb ?? parent.meta?.breadcrumb,
        authority: source.authority ? decorateAuthority(source.authority) : parent.meta?.authority,
        authorities: source.authorities ?? parent.meta?.authorities,
        order: source.order ?? 0,
      };
    } else {
      const source = route.meta;
      route.meta = {
        title: source.title ?? '',
        icon: source.icon ?? '',
        affix: source.affix ?? false,
        hidden: source.hidden ?? false,
        noCache: source.noCache ?? false,
        breadcrumb: source.breadcrumb ?? true,
        authority: decorateAuthority(source.authority),
        authorities: source.authorities ?? [],
        order: source.order ?? 0,
      };
    }
  } else {
    if (!route.children || route.children.length !== 1) {
      console.warn(`Path ${route.path} has no meta!`);
    }
    if (parent && parent.meta) {
      route.meta = {
        title: '',
        icon: parent.meta.icon,
        affix: parent.meta.affix,
        hidden: parent.meta.affix,
        noCache: parent.meta.affix,
        breadcrumb: parent.meta.affix,
        authority: parent.meta.authority,
        authorities: parent.meta.authorities,
        order: 0,
      };
    } else {
      route.meta = {
        title: '',
        icon: '',
        affix: false,
        hidden: false,
        noCache: false,
        breadcrumb: true,
        authority: {
          roles: [],
          accesses: [],
        },
        authorities: [],
        order: 0,
      };
    }
  }

  if (route.children && route.children.length > 0) {
    route.children = route.children.map(child => decorateRoute(child, route));
    route.redirect = route.redirect ?? route.children[0].path;
  }
  return route as Route;
};

export const decorateRoutes = (routes: RouteRecordRaw[]): Route[] => {
  return routes.map(route => decorateRoute(route));
};

export const decorateAsyncRoute = (route: RouteRecordRaw, parent?: RouteRecordRaw): Route => {
  // console.log('route', route);
  // console.log('parent', parent);
  if (route.path) {
    if (HttpUtil.isExternal(route.path)) {
      if (route.children && route.children.length > 0) {
        console.error(route);
        console.error('Components that have children should not have external links');
      }
    } else {
      route.path = path.join(parent?.path ?? '', route.path);
    }
  } else {
    console.error(route);
    console.error('The component has no path!');
  }
  if (!route.name) {
    route.name = Symbol.for(route.path);
  }
  // console.log('route', route);
  // console.log('parent', parent);
  if (route.meta) {
    if (parent && parent.meta) {
      const source = route.meta;
      route.meta = {
        title: source.title ?? '',
        icon: source.icon ?? '',
        affix: source.affix ?? parent.meta?.affix,
        hidden: source.hidden ?? parent.meta?.hidden,
        noCache: source.noCache ?? parent.meta?.noCache,
        breadcrumb: source.breadcrumb ?? parent.meta?.breadcrumb,
        order: source.order ?? 0,
      };
    } else {
      const source = route.meta;
      route.meta = {
        title: source.title ?? '',
        icon: source.icon ?? '',
        affix: source.affix ?? false,
        hidden: source.hidden ?? false,
        noCache: source.noCache ?? false,
        breadcrumb: source.breadcrumb ?? true,
        order: source.order ?? 0,
      };
    }
  } else {
    if (!route.children || route.children.length !== 1) {
      console.warn(`Path ${route.path} has no meta!`);
    }
    if (parent && parent.meta) {
      route.meta = {
        title: '',
        icon: parent.meta.icon,
        affix: parent.meta.affix,
        hidden: parent.meta.affix,
        noCache: parent.meta.affix,
        breadcrumb: parent.meta.affix,
        order: 0,
      };
    } else {
      route.meta = {
        title: '',
        icon: '',
        affix: false,
        hidden: false,
        noCache: false,
        breadcrumb: true,
        order: 0,
      };
    }
  }

  if (route.children && route.children.length > 0) {
    route.children = route.children.map(child => decorateRoute(child, route));
    route.redirect = route.redirect ?? route.children[0].path;
  }
  return route as Route;
};

export const decorateAsyncRoutes = (routes: RouteRecordRaw[]): Route[] => {
  return routes.map(route => decorateAsyncRoute(route));
};
